/********************************************************************************
* @file    os_api.c
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-04-03
* @brief   大部分RTX系统函数在：**\Keil_v5\Arm\Packs\ARM\CMSIS\5.6.0\CMSIS\RTOS\RTX\SRC
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
/* Private includes ----------------------------------------------------------*/
#include "cmsis_os.h"
#include "os_api.h"

/* Public function prototypes -----------------------------------------------*/
/*********************************OS_KERNEL***********************************/
os_status os_kernel_initialize(void)
{
    return (os_status)osKernelInitialize();
}

os_status os_kernel_start(void)
{
    return (os_status)osKernelStart();
}

os_status os_delay(uint32_t ms)
{
    return (os_status)osDelay(ms);
}

uint32_t os_get_tick(void)
{
    return osKernelSysTick();
}

extern void rt_tsk_lock(void);
os_status os_kernel_lock(void)
{
    rt_tsk_lock();
    return (os_status)0;
}

extern void rt_tsk_unlock(void);
os_status os_kernel_unlock(void)
{
    rt_tsk_unlock();
    return (os_status)0;
}
/************************************OS_THREAD************************************/
os_thread_id os_thread_create(const os_thread_def_t *thread_def, void *arg)
{
    return (os_thread_id)osThreadCreate((const osThreadDef_t *)thread_def, NULL);
}

/************************************OS_TIMER************************************/
os_timer_id os_timer_create(const os_timer_def_t *timer_def, os_timer_t type, void *arg)
{
    return osTimerCreate((const osTimerDef_t *)timer_def, (os_timer_type)type, arg);
}

os_status os_timer_start(os_timer_id timer_id, uint32_t millisec)
{
    if (timer_id == NULL)
    {
        return OS_ERROR_VALUE;
    }
    return (os_status)osTimerStart(timer_id, millisec);
}

os_status os_timer_stop(os_timer_id timer_id)
{
    if (timer_id == NULL)
    {
        return OS_ERROR_VALUE;
    }
    return (os_status)osTimerStop(timer_id);
}

/************************************OS_MAIL************************************/
os_mail_qid os_mail_create(const os_mailq_def_t *queue_def, os_thread_id thread_id)
{
    return (os_mail_qid)osMailCreate((const osMailQDef_t *)queue_def, thread_id);
}

void *os_mail_alloc(os_mail_qid queue_id, uint32_t millisec)
{
    return osMailAlloc((osMailQId)queue_id, millisec);
}

void *os_mail_clean_and_alloc(os_mail_qid queue_id, uint32_t millisec)
{
    return osMailCAlloc((osMailQId)queue_id, millisec);
}

os_status os_mail_put(os_mail_qid queue_id, void *mail)
{
    return (os_status)osMailPut((osMailQId)queue_id, mail);
}

os_event os_mail_get(os_mail_qid queue_id, uint32_t millisec, void *arg)
{
    osEvent event;
    os_event event_t;

    event = osMailGet((osMailQId)queue_id, millisec);
    memcpy(&event_t, &event, sizeof(osEvent));
    return event_t;
}

os_status os_mail_free(os_mail_qid queue_id, void *mail)
{
    return (os_status)osMailFree((osMailQId)queue_id, mail);
}

/************************************OS_POOL************************************/
os_pool_id os_pool_create(const os_pool_def_t *pool_def)
{
    return (os_pool_id)osPoolCreate((const osPoolDef_t *)pool_def);
}
void *os_pool_alloc(os_pool_id pool_id)
{
    return osPoolAlloc((osPoolId)pool_id);
}
void *os_pool_calloc(os_pool_id pool_id)
{
   return osPoolCAlloc((osPoolId)pool_id);
}
os_status os_pool_free(os_pool_id pool_id, void *block)
{
    return (os_status)osPoolFree((osPoolId)pool_id, block);
}
/************************************OS_MSG_QUEUE************************************/
/**
 * @brief  [消息队列] 创建消息队列空间
 * @note   NULL
 * @param  queue_def : 消息队列信息(大小)
 * @param  thread_id : 线程ID（可以无视不填）
 * @retval None
 */
os_message_qid os_message_create(const os_messageq_def_t *queue_def, os_thread_id thread_id)
{
    return (os_message_qid)osMessageCreate((const osMessageQDef_t *)queue_def, thread_id);
}

/**
 * @brief  [消息队列] 发送一组消息队列数据
 * @note   NULL
 * @param  queue_id: 消息队列ID
 * @param  info    : 消息指针
 * @param  millisec: 超时时间 0xFFFFFFFF 无限等待
 * @retval None
 */
os_status os_message_put(os_message_qid queue_id, uint32_t info, uint32_t millisec)
{
    return (os_status)osMessagePut((osMessageQId)queue_id, info, millisec); // Send Message
}

/**
 * @brief  [消息队列] 得到一组消息队列数据
 * @note   NULL
 * @param  queue_id: 消息队列ID
 * @param  millisec: 等待时间 0xFFFFFFFF 无限等待
 * @retval None
 */
os_event os_message_get(os_message_qid queue_id, uint32_t millisec)
{
    osEvent event;
    os_event event_t;
    event = osMessageGet((osMessageQId)queue_id, millisec);
    memcpy(&event_t, &event, sizeof(osEvent));
    return event_t;
}
/************************************OS_SIGNAL************************************/
extern int32_t isrSignalSet(osThreadId thread_id, int32_t signals);
int32_t isr_signal_set(os_thread_id thread_id, int32_t signals)
{
    return isrSignalSet(thread_id, signals);
}

int32_t os_signal_set(os_thread_id thread_id, int32_t signals)
{
    return osSignalSet(thread_id, signals);
}

int32_t os_signal_clear(os_thread_id thread_id, int32_t signals)
{
    return osSignalClear(thread_id, signals);
}

// signals = 0,则等待任意信号.
os_event os_signal_wait(int32_t signals, uint32_t millisec)
{
    osEvent event;
    os_event event_t;

    event = osSignalWait(signals, millisec);
    memcpy(&event_t, &event, sizeof(osEvent));
    return event_t;
}
